package com.qhs.framework.utils;

import sun.misc.BASE64Encoder;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import static sun.security.x509.CertificateAlgorithmId.ALGORITHM;

/**
 * 阿里云短信通道配置
 *
 * Created by xinchao on 2016/12/22 0022.
 */
public class SmsUtil {

    public static final String apiUrl="https://sms.aliyuncs.com/";

    public static final String SingleSendSms="SingleSendSms";  //操作接口名，系统规定参数

    public static final String templateCode="SMS_35050389";  //审核通过的短信模板的模板CODE（状态必须是验证通过）

    public static final String SignName="健科云";  //管理控制台中配置的短信签名（状态必须是验证通过）

    public static final String Format="JSON";  //返回值的类型

    public static final String Version = "2016-09-27";  //API版本号

    public static final String AccessKeyId = "LTAIytdeVEBfzqY8"; //阿里云颁发给用户的访问服务所用的密钥ID

    public static final String SignatureMethod = "HMAC-SHA1";

    public static final String SignatureVersion = "1.0";

    public static final String ENCODING = "UTF-8";

    public static final String SEPARATOR = "&";

    /**
     * 获取请求的时间戳。日期格式按照ISO8601标准表示，并需要使用UTC时间
     *
     * @return
     */
    public static String getISO8601Timestamp(){
        Date date = new Date();
        TimeZone tz = TimeZone.getTimeZone("UTC");
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(tz);
        String nowAsISO = df.format(date);
        return nowAsISO;
    }

    /**
     * 组装签名参数
     * @param recNum
     * @param jsonParams
     * @return
     */
    public static Map assembleParam(String recNum, String jsonParams){

        Map parameters = new HashMap();

        parameters.put("AccessKeyId", AccessKeyId);

        parameters.put("Action", SingleSendSms);

        parameters.put("Format", Format);

        parameters.put("ParamString", jsonParams);

        parameters.put("RecNum", recNum);

        parameters.put("RegionId", "");

        parameters.put("SignName", SignName);

        parameters.put("SignatureMethod", SignatureMethod);

        parameters.put("SignatureNonce", java.util.UUID.randomUUID().toString());

        parameters.put("SignatureVersion", SignatureVersion);

        parameters.put("TemplateCode", templateCode);

        parameters.put("Timestamp", getISO8601Timestamp());

        parameters.put("Version", Version);

        return parameters;
    }

    /**
     * 签名字符串
     * @return 签名结果
     */
   public static String sign(Map parameters) {

       String signature = "";
       String keyse = "testsecret&";
       try {
           // 对参数进行排序
           String[] sortedKeys = (String[]) parameters.keySet().toArray(new String[]{});
           Arrays.sort(sortedKeys);

           // 生成stringToSign字符串
           StringBuilder stringToSign = new StringBuilder();
           stringToSign.append("POST").append(SEPARATOR);
           stringToSign.append(percentEncode("/")).append(SEPARATOR);
           StringBuilder canonicalizedQueryString = new StringBuilder();

           for (String key : sortedKeys) {
               // 这里注意对key和value进行编码
               canonicalizedQueryString.append("&").append(percentEncode(key))
                       .append("=").append(percentEncode((String) parameters.get(key)));

           }
           // 这里注意对canonicalizedQueryString进行编码
           stringToSign.append(percentEncode(canonicalizedQueryString.toString().substring(1)));

           Mac mac = Mac.getInstance(ALGORITHM);
           mac.init(new SecretKeySpec(keyse.getBytes(ENCODING), ALGORITHM));
           byte[] signData = mac.doFinal(stringToSign.toString().getBytes(ENCODING));
           signature = new String(new BASE64Encoder().encode(signData));

           signature = percentEncode(signature);

       } catch (NoSuchAlgorithmException e) {
           e.printStackTrace();
       } catch (UnsupportedEncodingException e) {
           e.printStackTrace();
       } catch (InvalidKeyException e) {
           e.printStackTrace();
       }

       return signature;
   }

    /**
     * URL 编码规则编码后得到的字符串
     * @param value
     * @return
     * @throws UnsupportedEncodingException
     */
    private static String percentEncode(String value) throws UnsupportedEncodingException {

           return value != null ? URLEncoder.encode(value, "utf-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;

       }

}
